package com.jdbc.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import java.io.*;
import java.text.DecimalFormat;
import java.util.Map;

public class FileUtil {

	/**
	 * 输出指定文件的byte数组
	 * 
	 * @return
	 */
	public static void writeBytes(String filePath, OutputStream os) throws IOException {
		FileInputStream fis = null;
		try {
			File file = new File(filePath);
			if (!file.exists()) {
				throw new FileNotFoundException(filePath);
			}
			fis = new FileInputStream(file);
			byte[] b = new byte[1024];
			int length;
			while ((length = fis.read(b)) > 0) {
				os.write(b, 0, length);
			}
		} catch (IOException e) {
			throw e;
		} finally {
			if (os != null) {
				try {
					os.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	public static String getFileExtension(String fileName){
		fileName = StringUtil.filterNullToEmpty(fileName);
		int lastIndex = fileName.lastIndexOf('.');
		String fileExtension = fileName.substring(lastIndex+1);
		return fileExtension;
	}

		private final static Logger log = LoggerFactory.getLogger(FileUtil.class);
		

		/**
		 * 删除指定的文件。
		 * @param filePath
		 * @return
		 */
		public static boolean delFile(File filePath){
			if(!filePath.exists()){
				return true;
			}
			if(filePath.isFile()){
				return filePath.delete();
			}
			return false;
		}
		/**
		 * 创建文件路径的上级目录,即创建文件的目录路径创建
		 * @param filePath
		 * @return
		 */
		public static boolean createParentDirectory(File filePath){
			File parentPath = filePath.getParentFile();
			if(parentPath.isFile()){log.warn("创建目录失败，名称已被占用"); return false;}
			if(!parentPath.exists()){
				return parentPath.mkdirs();
			}
			return true;
		}
		
		
		
		
		/**
		 * 得到文件基于根路径的相对路径。例如 root a, rootInnerFilePath a\b\c,结果为 b\c
		 * @param root
		 * @param rootInnerFilePath
		 * @return 字符串，形如：b\c，路径分隔符使用系统默认的（windows[\],linux[/]）
		 */
		public static String getFileRelativePath(File root,File rootInnerFilePath){
			try {
				String rootStr = root.getCanonicalPath()+File.separator;
				String filePathStr = rootInnerFilePath.getCanonicalPath();
				if(filePathStr.startsWith(rootStr)){
					return filePathStr.substring(rootStr.length());
				}
				else{
					log.warn("rootInnerFilePath 必须是 root 的内部路径");
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
			return "";
		}
		/**
		 * 得到文件基于根路径的相对路径中各级目录名（数组）。例如 root a, rootInnerFilePath a\b\c,结果为["b","c"]
		 * @param root 根路径
		 * @param rootInnerFilePath 根路径下的某个内部路径
		 * @return 数组，形如：["b","c"]
		 */
		public static String[] getFileRelativePathSegment(File root,File rootInnerFilePath){
			String[] seg = {};
			String relativePath = getFileRelativePath(root, rootInnerFilePath);
			if(relativePath.length()>0){
				String separator = File.separator;
				if(File.separator.equals("\\")){
					separator = "\\\\";
				}
				seg = relativePath.split(separator);
			}
			return seg;
		}
		
		
		
		/**
		 * 递归搜索指定目录下的“文件”，将所有“文件”放入Map
		 * @param rooFile 计算相对路径的基准根目录
		 * @param dirFile 当前要搜索的目录
		 * @param fileMap Map中 K-文件的相对路径（相对于指定的根目录），V-文件File对象
		 */
		private static void recursionSearchFile(File rooFile,File dirFile, Map<String,File> fileMap){
			for(File file : dirFile.listFiles()){
				if(file.isFile()){
					fileMap.put(getFileRelativePath(rooFile, file), file);
				}
				if(file.isDirectory()){
					recursionSearchFile(rooFile,file,fileMap);
				}
			}
		}
		
		/**
		 * 搜索指定目录的所有后代目录中的“文件”，将所有“文件”放入Map
		 * @param dirFile 扫描的基准根目录
		 * @param fileMap Map中 K-文件的相对路径（相对于指定的根目录），V-文件File对象
		 */
		public static void getDescendantFile(File dirFile, Map<String,File> fileMap){
			if(dirFile.isDirectory()){
				recursionSearchFile(dirFile,dirFile, fileMap);
			}
			else{
				log.warn("指定的文件目录["+dirFile.getPath()+"]不存在或不是目录");
			}
		}
		
		/**
		 * units是可选的参数，默认格式为[B, KB, MB, GB, TB],最高支持到TB。
		 * <p>如果设置units为[B, KB, MB] 代表所有超过1MB的文件都显示 MB为单位。
		 * @param fileSize 文件的字节数（B）
		 * @param units 设置每个等级的单位后缀名,从B开始定义，不能间隔。
		 * @return
		 */
		public static String getFileSizeFormat(long fileSize, String... units){
	        String[] unit = new String[]{"B","KB","MB","GB","TB"};
	        if(units != null && units.length>0){
	        	unit = units;
	        }
	        double size = fileSize;
	        int i=0;
	        for(; size >= 1024 && i<unit.length-1;i++){
	        	size = size/1024;
	        }
	        return decimalFormat.format(size)+unit[i];
		}


	/**
	 * 保存文件的时候指定文件名和文件的保存路径
	 * @param filename
	 * @param path
	 * @return
	 */
	public static String getDirPath(String filename, File path) {
		   JFileChooser parseDir = new JFileChooser();
		   parseDir.setCurrentDirectory(path);
		   parseDir.setAcceptAllFileFilterUsed(false);
		   parseDir.setSelectedFile(new File(filename));
		   int result = parseDir.showSaveDialog(null);
		   if (result == JFileChooser.APPROVE_OPTION) {
			   return parseDir.getSelectedFile().getAbsolutePath();
		   } else {
			   return "";
		   }
	   }


	/**
	 * 打开文件所在的目录
	 *
	 * @param destFileName
	 * @throws IOException
	 */
	public static void openDirFile(String destFileName) throws IOException {
		File file = new File(destFileName);
		java.awt.Desktop.getDesktop().open(file);
	}

		private static DecimalFormat decimalFormat = new DecimalFormat("#.##");

}
